Import Modules¶

In [1]:
import os, shutil, json, zipfile, random, math, urllib
from pathlib import Path
from PIL import Image
import cv2
import numpy as np
import tensorflow as tf
from matplotlib import pyplot as plt
import seaborn as sns
import matplotlib.image as mpimg
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout, Input
from tensorflow.keras.metrics import Precision, Recall, BinaryAccuracy
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import layers
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix

print("tensorflow version: ",tf.__version__)
2024-05-08 15:14:19.947694: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered
2024-05-08 15:14:19.947845: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
2024-05-08 15:14:20.169256: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
tensorflow version:  2.15.0

Configure Plot¶

In [2]:
plt.rcParams['font.size'] = 14
plt.rcParams['figure.subplot.wspace'] = 0.4
plt.rcParams['figure.subplot.hspace'] = 0.6
plt.rcParams['axes.titley'] = 1.0

GPU Config¶

In [3]:
# Avoid OOM errors by setting GPU Memory Consumption Growth
def gpu_config():
    gpus = tf.config.experimental.list_physical_devices('GPU')
    for gpu in gpus: 
        tf.config.experimental.set_memory_growth(gpu, True)
    print(tf.config.list_physical_devices('GPU'))      
In [4]:
try:
    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()
    tf.config.experimental_connect_to_cluster(tpu)
    tf.tpu.experimental.initialize_tpu_system(tpu)
    print('Running on TPU ', tpu.cluster_spec().as_dict()['worker'])
except ValueError:
    gpu_config()
[]

Utils¶

In [5]:
def get_file_paths(folder_path):
    return [os.path.join(folder_path, file) for file in os.listdir(folder_path)]

def grid_plot(images_path_list):
    num_images = len(images_path_list)
    num_columns = 3
    num_rows = (num_images + num_columns - 1) // num_columns
    fig, axes = plt.subplots(nrows=num_rows, ncols=num_columns, figsize=(15, 4*num_rows))
    if num_rows == 1:
        axes = axes.reshape(1, -1)
    for i, image_path in enumerate(images_path_list):
        row = i // num_columns
        col = i % num_columns
        
        image = plt.imread(image_path)
        axes[row, col].imshow(image)
        folder_name = os.path.basename(os.path.dirname(image_path))
        image_name = os.path.basename(image_path)
        axes[row, col].set_title(folder_name + '/' + image_name)
        axes[row, col].axis('on')
        
    plt.tight_layout()
    plt.show()
    
def delete_files_and_folders(folder_path):
    for item in os.listdir(folder_path):
        item_path = os.path.join(folder_path, item)
        
        if os.path.isfile(item_path):
            os.unlink(item_path)
        elif os.path.isdir(item_path):
            shutil.rmtree(item_path)

    print("All files and folders inside", folder_path, "have been deleted.")
    print(os.listdir(folder_path))
    
def get_directory_size(directory):
    """
    Returns the size of the directory in bytes.
    """
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(directory):
        for f in filenames:
            file_path = os.path.join(dirpath, f)
            total_size += os.path.getsize(file_path)
    return total_size

def print_subfolders(root_folder):
    for entry in os.scandir(root_folder):
        if entry.is_dir():
            full_path = os.path.join(root_folder, entry.name)
            print(full_path, len(os.listdir(full_path)))
            print_subfolders(full_path)

def convert_bytes(size):
    for unit in ['', 'K', 'M', 'G', 'T', 'P']:
        if size < 1024:
            return f"{size:.2f} {unit}B"
        size /= 1024
        
def create_directory(directories):
    for directory in directories:
        if not os.path.exists(directory):
            os.mkdir(directory)
            print('Created {}'.format(directory))
        else:
            print('{} exists'.format(directory))
            
def copy_images(images_list, to_dir):
    if not os.path.exists(to_dir):
        os.mkdir(to_dir)
    
    for image_path in images_list:
        image_name = os.path.basename(image_path)
        destination_path = os.path.join(to_dir, image_name)
        shutil.copy(image_path, destination_path)
    
    print("Images copied successfully to", to_dir, len(os.listdir(to_dir)))
    
def move_images(images_list, to_dir):
    if not os.path.exists(to_dir):
        os.mkdir(to_dir)
    
    for image_path in images_list:
        image_name = os.path.basename(image_path)
        destination_path = os.path.join(to_dir, image_name)
        shutil.move(image_path, destination_path)
    
    print("Images moved successfully to", to_dir, len(os.listdir(to_dir)))
    
def move(from_dir, start, end, to_dir):
    images = os.listdir(from_dir)[start:end]
    images_paths = [os.path.join(from_dir, image) for image in images]
    move_images(images_paths, to_dir) 
    print(len(os.listdir(to_dir)))
    
def copy(from_dir, start, end, to_dir):
    images = os.listdir(from_dir)[start:end]
    images_paths = [os.path.join(from_dir, image) for image in images]
    copy_images(images_paths, to_dir) 
    print(len(os.listdir(to_dir)))
    
def data_info(directory):
    images = os.listdir(directory)
    print(f"Images in {os.path.basename(directory)} : {len(images)}")
    extensions = [os.path.splitext(file)[1] for file in images]
    unique_extensions = set(extensions)
    print("Images are present in these extensions:", unique_extensions)
    
def check_image_readability(folder_path):
    file_list = os.listdir(folder_path)
    
    errored_images = []
    correct_images = []

    for file_name in file_list:
        file_path = os.path.join(folder_path, file_name)
        try:
            with Image.open(file_path) as img:
                img.load()
            correct_images.append(file_path)
        except Exception as e:
            print(e)
            print(file_path)
            errored_images.append(file_path)
            continue
    
    if errored_images:
        print("There are errored images")
    else:
        print("All images are readable.")
    return errored_images, correct_images

def remove_images(images_list):
    if images_list:
        for image in images_list:
            os.remove(image)
        print(len(images_list),'removed')
    else:
        pass

Create Folders¶

In [12]:
working_dir = os.getcwd()
dataset = os.path.join(working_dir, 'dataset')

logs_dir = os.path.join(os.getcwd(), 'logs')
models_dir = os.path.join(os.getcwd(), 'models')
hist_dir = os.path.join(os.getcwd(), 'history')
figures_dir = os.path.join(os.getcwd(), 'figures')
zipfiles_dir = os.path.join(os.getcwd(), 'zipfiles')
train_dir = os.path.join(os.getcwd(), 'train')
test_dir = os.path.join(os.getcwd(), 'test')
val_dir = os.path.join(os.getcwd(), 'val')

create_directory([logs_dir, models_dir, hist_dir, figures_dir, zipfiles_dir,train_dir,test_dir,val_dir])
/kaggle/working/logs exists
/kaggle/working/models exists
/kaggle/working/history exists
/kaggle/working/figures exists
/kaggle/working/zipfiles exists
/kaggle/working/train exists
/kaggle/working/test exists
/kaggle/working/val exists
In [60]:
delete_files_and_folders(models_dir)
delete_files_and_folders(train_dir)
delete_files_and_folders(test_dir)
delete_files_and_folders(val_dir)

# delete_files_and_folders(hist_dir)
# delete_files_and_folders(logs_dir)
# delete_files_and_folders(figures_dir)
# delete_files_and_folders(zipfiles_dir)
# delete_files_and_folders(os.getcwd())
All files and folders inside /kaggle/working/models have been deleted.
[]
All files and folders inside /kaggle/working/train have been deleted.
[]
All files and folders inside /kaggle/working/test have been deleted.
[]
All files and folders inside /kaggle/working/val have been deleted.
[]

Assign Paths¶

In [29]:
dataset_dir_1 = '/kaggle/input/chest-xray-pneumonia'
dataset_dir_2 = '/kaggle/input/pneumonia-xray-images'
dataset_dir_3 = '/kaggle/input/chest-xray-pneumoniacovid19tuberculosis'


project_name = 'Chest-XRay-Pneumonia'+'_'

Exploratory Analysis¶

Get Dataset Info¶

In [9]:
dataset_dir = dataset_dir_1

print(dataset_dir,'\n')
print(project_name,'\n')

print_subfolders(dataset_dir)

size_in_bytes = get_directory_size(dataset_dir)
readable_size = convert_bytes(size_in_bytes)
print(f"\nDirectory size of {dataset_dir}: {readable_size}\n")
/kaggle/input/chest-xray-pneumonia 

Chest-XRay-Pneumonia_ 

/kaggle/input/chest-xray-pneumonia/chest_xray 5
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray 4
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/val 3
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/val/PNEUMONIA 9
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/val/NORMAL 9
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/test 3
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/test/PNEUMONIA 390
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/test/NORMAL 234
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/train 3
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/train/PNEUMONIA 3876
/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/train/NORMAL 1342
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX 2
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray 6
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray/val 3
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray/val/PNEUMONIA 9
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray/val/NORMAL 9
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray/test 5
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray/test/PNEUMONIA 390
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray/test/NORMAL 234
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray/train 5
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray/train/PNEUMONIA 3876
/kaggle/input/chest-xray-pneumonia/chest_xray/__MACOSX/chest_xray/train/NORMAL 1342
/kaggle/input/chest-xray-pneumonia/chest_xray/val 2
/kaggle/input/chest-xray-pneumonia/chest_xray/val/PNEUMONIA 8
/kaggle/input/chest-xray-pneumonia/chest_xray/val/NORMAL 8
/kaggle/input/chest-xray-pneumonia/chest_xray/test 2
/kaggle/input/chest-xray-pneumonia/chest_xray/test/PNEUMONIA 390
/kaggle/input/chest-xray-pneumonia/chest_xray/test/NORMAL 234
/kaggle/input/chest-xray-pneumonia/chest_xray/train 2
/kaggle/input/chest-xray-pneumonia/chest_xray/train/PNEUMONIA 3875
/kaggle/input/chest-xray-pneumonia/chest_xray/train/NORMAL 1341

Directory size of /kaggle/input/chest-xray-pneumonia: 2.31 GB

In [10]:
dataset_dir = dataset_dir_2

print(dataset_dir,'\n')
print(project_name,'\n')

print_subfolders(dataset_dir)

size_in_bytes = get_directory_size(dataset_dir)
readable_size = convert_bytes(size_in_bytes)
print(f"\nDirectory size of {dataset_dir}: {readable_size}\n")
/kaggle/input/pneumonia-xray-images 

Chest-XRay-Pneumonia_ 

/kaggle/input/pneumonia-xray-images/val 2
/kaggle/input/pneumonia-xray-images/val/normal 267
/kaggle/input/pneumonia-xray-images/val/opacity 773
/kaggle/input/pneumonia-xray-images/test 2
/kaggle/input/pneumonia-xray-images/test/normal 234
/kaggle/input/pneumonia-xray-images/test/opacity 390
/kaggle/input/pneumonia-xray-images/train 2
/kaggle/input/pneumonia-xray-images/train/normal 1082
/kaggle/input/pneumonia-xray-images/train/opacity 3110

Directory size of /kaggle/input/pneumonia-xray-images: 1.15 GB

In [11]:
dataset_dir = dataset_dir_3

print(dataset_dir,'\n')
print(project_name,'\n')

print_subfolders(dataset_dir)

size_in_bytes = get_directory_size(dataset_dir)
readable_size = convert_bytes(size_in_bytes)
print(f"\nDirectory size of {dataset_dir}: {readable_size}\n")
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis 

Chest-XRay-Pneumonia_ 

/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/val 4
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/val/PNEUMONIA 8
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/val/NORMAL 8
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/val/COVID19 10
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/val/TURBERCULOSIS 12
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/test 4
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/test/PNEUMONIA 390
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/test/NORMAL 234
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/test/COVID19 106
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/test/TURBERCULOSIS 41
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/train 4
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/train/PNEUMONIA 3875
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/train/NORMAL 1341
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/train/COVID19 460
/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/train/TURBERCULOSIS 650

Directory size of /kaggle/input/chest-xray-pneumoniacovid19tuberculosis: 1.79 GB

Move Images to Working¶

In [62]:
pneumonia_folders = ['/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/train/PNEUMONIA', '/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/test/PNEUMONIA', '/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/val/PNEUMONIA', '/kaggle/input/pneumonia-xray-images/train/opacity', '/kaggle/input/pneumonia-xray-images/test/opacity' ,'/kaggle/input/pneumonia-xray-images/val/opacity', '/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/train/PNEUMONIA', '/kaggle/input/chest-xray-pneumonia/chest_xray/chest_xray/test/PNEUMONIA']
In [47]:
pneumonia_images = []
for folder in pneumonia_folders:
    images = get_file_paths(folder)
    pneumonia_images += images
        
len(pneumonia_images)
Out[47]:
12812
In [46]:
normal_folders = ['/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/train/NORMAL', '/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/test/NORMAL', '/kaggle/input/chest-xray-pneumoniacovid19tuberculosis/val/NORMAL', '/kaggle/input/pneumonia-xray-images/train/normal', '/kaggle/input/pneumonia-xray-images/test/normal', '/kaggle/input/pneumonia-xray-images/val/normal', '/kaggle/input/chest-xray-pneumonia/chest_xray/train/NORMAL', '/kaggle/input/chest-xray-pneumonia/chest_xray/test/NORMAL', '/kaggle/input/chest-xray-pneumonia/chest_xray/val/NORMAL']
In [48]:
normal_images = []
for folder in normal_folders:
    images = get_file_paths(folder)
    normal_images += images
        
len(normal_images)
Out[48]:
4749

Train¶

In [67]:
to_dir = train_dir+'/'+'normal'
copy_images(normal_images[:], to_dir)
Images copied successfully to /kaggle/working/train/normal 1583
In [68]:
to_dir = train_dir+'/'+'pneumonia'
copy_images(pneumonia_images[:], to_dir)
Images copied successfully to /kaggle/working/train/pneumonia 4274

Test¶

In [69]:
from_dir = '/kaggle/working/train/normal'
to_dir = test_dir+'/'+'normal'
move(from_dir, 0, 100, to_dir)
Images moved successfully to /kaggle/working/test/normal 100
100
In [70]:
from_dir = '/kaggle/working/train/pneumonia'
to_dir = test_dir+'/'+'pneumonia'
move(from_dir, 0, 100, to_dir)
Images moved successfully to /kaggle/working/test/pneumonia 100
100
In [71]:
images_paths = get_file_paths('/kaggle/working/train/pneumonia')

remove_images(images_paths[0:2691])
2691 removed

Assign paths after moving images¶

In [9]:
root_dir = '/kaggle/working/train/'

class_1 = '/kaggle/working/train/normal'
class_2 = '/kaggle/working/train/pneumonia'

test_dir_1 = '/kaggle/working/test/normal'
test_dir_2 = '/kaggle/working/test/pneumonia'

Get Train Data info and Readability¶

In [73]:
data_info(class_1)
data_info(class_2)

errored_images_1, correct_images_1 = check_image_readability(class_1)
print(len(errored_images_1), len(correct_images_1))

errored_images_2, correct_images_2 = check_image_readability(class_2)
print(len(errored_images_2), len(correct_images_2))
Images in normal : 1483
Images are present in these extensions: {'.jpeg'}
Images in pneumonia : 1483
Images are present in these extensions: {'', '.jpeg'}
All images are readable.
0 1483
cannot identify image file '/kaggle/working/train/pneumonia/.DS_Store'
/kaggle/working/train/pneumonia/.DS_Store
There are errored images
1 1482
In [74]:
remove_images(errored_images_1)
remove_images(errored_images_2)
1 removed
In [75]:
data_info(test_dir_1)
data_info(test_dir_2)
Images in normal : 100
Images are present in these extensions: {'.jpeg'}
Images in pneumonia : 100
Images are present in these extensions: {'.jpeg'}
In [76]:
errored_images_1_test, correct_images_1_test = check_image_readability(test_dir_1)
print(len(errored_images_1_test), len(correct_images_1_test))

errored_images_2_test, correct_images_2_test = check_image_readability(test_dir_2)
print(len(errored_images_2_test), len(correct_images_2_test))
All images are readable.
0 100
All images are readable.
0 100

Plot Distribution of Images¶

In [77]:
labels = [os.path.basename(class_1), os.path.basename(class_2)]
sizes = [len(os.listdir(class_1)), len(os.listdir(class_2))]
plt.figure(figsize=(6, 6))
plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140)
title = '{} Distribution of Images'.format(project_name)
plt.title(title)
plt.savefig(figures_dir+'/'+title+'.png')
print('{} saved to {}'.format(title, figures_dir))
plt.show()
Chest-XRay-Pneumonia_ Distribution of Images saved to /kaggle/working/figures
No description has been provided for this image

Plot Images in Grid¶

In [78]:
grid_plot(correct_images_1[:12])
No description has been provided for this image
In [79]:
grid_plot(correct_images_2[:12])
No description has been provided for this image

Preprocessing¶

In [6]:
tf.keras.utils.image_dataset_from_directory
Out[6]:
<function keras.src.utils.image_dataset_utils.image_dataset_from_directory(directory, labels='inferred', label_mode='int', class_names=None, color_mode='rgb', batch_size=32, image_size=(256, 256), shuffle=True, seed=None, validation_split=None, subset=None, interpolation='bilinear', follow_links=False, crop_to_aspect_ratio=False, pad_to_aspect_ratio=False, data_format=None, verbose=True)>

Load Data¶

In [7]:
input_shape = (150, 150, 3)
In [10]:
data = tf.keras.utils.image_dataset_from_directory(root_dir, image_size=(input_shape[0], input_shape[1]))
total_images_train = len(data.file_paths)
print('{} Images loaded'.format(total_images_train))
Found 2965 files belonging to 2 classes.
2965 Images loaded
In [13]:
test_data = tf.keras.utils.image_dataset_from_directory(test_dir, image_size=(input_shape[0], input_shape[1]))
total_images_test = len(test_data.file_paths)
print('{} Images loaded'.format(total_images_test))
Found 200 files belonging to 2 classes.
200 Images loaded

Check class labels¶

In [14]:
class_labels = {}
print('Classes found {}'.format(data.class_names))
for idx, class_name in enumerate(data.class_names):
    print(f"Class Label: {idx}, Class Name: {class_name}")
    class_labels[class_name] = idx
print(class_labels,'\n')

print('Type of Data : ',type(data),'\n')
print('Number of batches : ',len(data),'\n')
print(data.element_spec)
Classes found ['normal', 'pneumonia']
Class Label: 0, Class Name: normal
Class Label: 1, Class Name: pneumonia
{'normal': 0, 'pneumonia': 1} 

Type of Data :  <class 'tensorflow.python.data.ops.prefetch_op._PrefetchDataset'> 

Number of batches :  93 

(TensorSpec(shape=(None, 150, 150, 3), dtype=tf.float32, name=None), TensorSpec(shape=(None,), dtype=tf.int32, name=None))

When you load data using tf.keras.utils.image_dataset_from_directory, it automatically batches the data according to the specified batch_size. Since you didn't specify the batch_size in your code, it defaulted to 32. Therefore, the total number of batches is calculated as:

Total number of batches = Total number of images / Batch size

In this case: Batch size = 32

So, the total number of batches = Total number of images / 32 = batches

Grid Plot for a batch of preprocessed images¶

In [15]:
data_iterator = data.as_numpy_iterator()
print(type(data_iterator))
<class 'tensorflow.python.data.ops.dataset_ops.NumpyIterator'>
In [16]:
batch = data_iterator.next()
In [17]:
print("Type of batch:", type(batch))
print("Length of batch:", len(batch))
print("Shape of batch[0] (Images):", batch[0].shape)
print("Shape of batch[1] (Labels):", batch[1].shape)
print("Type of batch[0] (Images):", type(batch[0]))
print("Type of batch[1] (Labels):", type(batch[1]))
print("Minimum value in batch[0]:", batch[0].min())
print("Maximum value in batch[0]:", batch[0].max())
Type of batch: <class 'tuple'>
Length of batch: 2
Shape of batch[0] (Images): (32, 150, 150, 3)
Shape of batch[1] (Labels): (32,)
Type of batch[0] (Images): <class 'numpy.ndarray'>
Type of batch[1] (Labels): <class 'numpy.ndarray'>
Minimum value in batch[0]: 0.0
Maximum value in batch[0]: 255.0
In [88]:
grid_shape = (3, 3)
total_images = 9
num_rows =3
num_cols = 3

fig, ax = plt.subplots(nrows=num_rows, ncols=num_cols, figsize=(20, 20))
for idx, img in enumerate(batch[0][:total_images]):
    row = idx // grid_shape[1]  
    col = idx % grid_shape[1]  
    ax[row, col].imshow(img.astype(int))
    class_label = batch[1][idx]
    class_name = data.class_names[class_label]
    ax[row, col].title.set_text(f"Class: {class_label} - {class_name}")

plt.tight_layout()
plt.show()
No description has been provided for this image

Normalize images from 0-255 to 0-1¶

In [18]:
scaled_data = data.map(lambda x,y: (x/255, y))
scaled_test_data = test_data.map(lambda x,y: (x/255, y))
In [19]:
print(type(scaled_data), len(scaled_data))
<class 'tensorflow.python.data.ops.map_op._MapDataset'> 93
In [20]:
scaled_batch = scaled_data.as_numpy_iterator().next()
In [21]:
print("Type of scaled_batch:", type(scaled_batch))
print("Length of scaled_batch:", len(scaled_batch))
print("Shape of scaled_batch[0] (Images):", scaled_batch[0].shape)
print("Shape of scaled_batch[1] (Labels):", scaled_batch[1].shape)
print("Type of scaled_batch[0] (Images):", type(scaled_batch[0]))
print("Type of scaled_batch[1] (Labels):", type(scaled_batch[1]))
print("Minimum value in scaled_batch[0]:", scaled_batch[0].min())
print("Maximum value in scaled_batch[0]:", scaled_batch[0].max())
Type of scaled_batch: <class 'tuple'>
Length of scaled_batch: 2
Shape of scaled_batch[0] (Images): (32, 150, 150, 3)
Shape of scaled_batch[1] (Labels): (32,)
Type of scaled_batch[0] (Images): <class 'numpy.ndarray'>
Type of scaled_batch[1] (Labels): <class 'numpy.ndarray'>
Minimum value in scaled_batch[0]: 0.0
Maximum value in scaled_batch[0]: 1.0

Make train test valid split¶

In [22]:
train_size = int(len(scaled_data)*.7)
val_size = int(len(scaled_data)*.3)
test_size = int(len(scaled_test_data))
In [23]:
print("train_size:", train_size, 'batches out of ',len(scaled_data))
print("val_size:", val_size, 'batches out of ',len(scaled_data))
print("test_size:", test_size, 'batches out of ',len(scaled_test_data))
train_size: 65 batches out of  93
val_size: 27 batches out of  93
test_size: 7 batches out of  7
In [24]:
train = scaled_data.take(train_size)
val = scaled_data.skip(train_size).take(val_size)
test = scaled_test_data.take(test_size)
In [25]:
print("train:", train_size, 'batches out of ',len(train))
print("val:", val_size, 'batches out of ',len(val))
print("test:", test_size, 'batches out of ',len(test))
train: 65 batches out of  65
val: 27 batches out of  27
test: 7 batches out of  7

Create Model¶

In [26]:
def conv2d_seq():
    model_name = project_name + 'conv2d_seq_model'

    model = Sequential([
        Input(shape=input_shape),
        Conv2D(16, (3, 3), strides=1, activation='relu'),
        MaxPooling2D(),
        Conv2D(32, (3, 3), strides=1, activation='relu'),
        MaxPooling2D(),
        Conv2D(16, (3, 3), strides=1, activation='relu'),
        MaxPooling2D(),
        Flatten(),
        Dense(256, activation='relu'),
        Dense(1, activation='sigmoid')
    ], name=model_name)
    
    return model

def iv3():
    model_name = project_name + 'iv3_model'
    
    weights_url = "https://storage.googleapis.com/mledu-datasets/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5"
    weights_file = "inception_v3.h5"
    urllib.request.urlretrieve(weights_url, weights_file)
    
    pre_trained_model = InceptionV3(input_shape=(150, 150, 3),
                                include_top=False,
                                weights=None)

    pre_trained_model.load_weights(weights_file)
    
    for layer in pre_trained_model.layers:
        layer.trainable = False
        
    last_layer = pre_trained_model.get_layer('mixed7')
    print('Last layer output shape: ', last_layer.output.shape)
    last_output = last_layer.output
    
    x = layers.Flatten()(last_output)
    x = layers.Dense(1024, activation='relu')(x)
    x = layers.Dense(1, activation='sigmoid')(x)

    model = Model(pre_trained_model.input, x, name=model_name)
    
    return model
In [27]:
def get_checkpoint(count):
    if count == 'all':
        model_name = project_name + 'conv2d_seq_model'
        checkpoint_filepath = models_dir + "/" + model_name + "epoch_{epoch:02d} acc_{accuracy:.4f} loss_{loss:.4f} val_acc_{val_accuracy:.4f} val_loss_{val_loss:.4f}.keras"
        checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(
            filepath=checkpoint_filepath,
            save_weights_only=False,
            save_freq='epoch'
        )
        print(checkpoint_filepath)
        return checkpoint_callback
    
    elif count == 'one':
        model_name = project_name + 'iv3_model'
        checkpoint_filepath = models_dir + "/" + model_name + "epoch_{epoch:02d} acc_{accuracy:.4f} loss_{loss:.4f} val_acc_{val_accuracy:.4f} val_loss_{val_loss:.4f}.keras"
    
        checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(
            filepath=checkpoint_filepath,
            save_best_only=True, 
            monitor='val_accuracy',
            mode='max', 
            verbose=1
        )
        print(checkpoint_filepath)
    
        return checkpoint_callback
In [30]:
model = iv3()
Last layer output shape:  (None, 7, 7, 768)
In [31]:
model_checkpoint = get_checkpoint('one')
/kaggle/working/models/Chest-XRay-Pneumonia_iv3_modelepoch_{epoch:02d} acc_{accuracy:.4f} loss_{loss:.4f} val_acc_{val_accuracy:.4f} val_loss_{val_loss:.4f}.keras
In [32]:
model.summary()
Model: "Chest-XRay-Pneumonia_iv3_model"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)        ┃ Output Shape      ┃    Param # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer         │ (None, 150, 150,  │          0 │ -                 │
│ (InputLayer)        │ 3)                │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d (Conv2D)     │ (None, 74, 74,    │        864 │ input_layer[0][0] │
│                     │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalization │ (None, 74, 74,    │         96 │ conv2d[0][0]      │
│ (BatchNormalizatio… │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation          │ (None, 74, 74,    │          0 │ batch_normalizat… │
│ (Activation)        │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_1 (Conv2D)   │ (None, 72, 72,    │      9,216 │ activation[0][0]  │
│                     │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 72, 72,    │         96 │ conv2d_1[0][0]    │
│ (BatchNormalizatio… │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_1        │ (None, 72, 72,    │          0 │ batch_normalizat… │
│ (Activation)        │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_2 (Conv2D)   │ (None, 72, 72,    │     18,432 │ activation_1[0][… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 72, 72,    │        192 │ conv2d_2[0][0]    │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_2        │ (None, 72, 72,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ max_pooling2d       │ (None, 35, 35,    │          0 │ activation_2[0][… │
│ (MaxPooling2D)      │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_3 (Conv2D)   │ (None, 35, 35,    │      5,120 │ max_pooling2d[0]… │
│                     │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 35, 35,    │        240 │ conv2d_3[0][0]    │
│ (BatchNormalizatio… │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_3        │ (None, 35, 35,    │          0 │ batch_normalizat… │
│ (Activation)        │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_4 (Conv2D)   │ (None, 33, 33,    │    138,240 │ activation_3[0][… │
│                     │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 33, 33,    │        576 │ conv2d_4[0][0]    │
│ (BatchNormalizatio… │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_4        │ (None, 33, 33,    │          0 │ batch_normalizat… │
│ (Activation)        │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ max_pooling2d_1     │ (None, 16, 16,    │          0 │ activation_4[0][… │
│ (MaxPooling2D)      │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_8 (Conv2D)   │ (None, 16, 16,    │     12,288 │ max_pooling2d_1[… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_8[0][0]    │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_8        │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_6 (Conv2D)   │ (None, 16, 16,    │      9,216 │ max_pooling2d_1[… │
│                     │ 48)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_9 (Conv2D)   │ (None, 16, 16,    │     55,296 │ activation_8[0][… │
│                     │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        144 │ conv2d_6[0][0]    │
│ (BatchNormalizatio… │ 48)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        288 │ conv2d_9[0][0]    │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_6        │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 48)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_9        │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ average_pooling2d   │ (None, 16, 16,    │          0 │ max_pooling2d_1[… │
│ (AveragePooling2D)  │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_5 (Conv2D)   │ (None, 16, 16,    │     12,288 │ max_pooling2d_1[… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_7 (Conv2D)   │ (None, 16, 16,    │     76,800 │ activation_6[0][… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_10 (Conv2D)  │ (None, 16, 16,    │     82,944 │ activation_9[0][… │
│                     │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_11 (Conv2D)  │ (None, 16, 16,    │      6,144 │ average_pooling2… │
│                     │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_5[0][0]    │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_7[0][0]    │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        288 │ conv2d_10[0][0]   │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │         96 │ conv2d_11[0][0]   │
│ (BatchNormalizatio… │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_5        │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_7        │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_10       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_11       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ mixed0              │ (None, 16, 16,    │          0 │ activation_5[0][… │
│ (Concatenate)       │ 256)              │            │ activation_7[0][… │
│                     │                   │            │ activation_10[0]… │
│                     │                   │            │ activation_11[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_15 (Conv2D)  │ (None, 16, 16,    │     16,384 │ mixed0[0][0]      │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_15[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_15       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_13 (Conv2D)  │ (None, 16, 16,    │     12,288 │ mixed0[0][0]      │
│                     │ 48)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_16 (Conv2D)  │ (None, 16, 16,    │     55,296 │ activation_15[0]… │
│                     │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        144 │ conv2d_13[0][0]   │
│ (BatchNormalizatio… │ 48)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        288 │ conv2d_16[0][0]   │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_13       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 48)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_16       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ average_pooling2d_1 │ (None, 16, 16,    │          0 │ mixed0[0][0]      │
│ (AveragePooling2D)  │ 256)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_12 (Conv2D)  │ (None, 16, 16,    │     16,384 │ mixed0[0][0]      │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_14 (Conv2D)  │ (None, 16, 16,    │     76,800 │ activation_13[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_17 (Conv2D)  │ (None, 16, 16,    │     82,944 │ activation_16[0]… │
│                     │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_18 (Conv2D)  │ (None, 16, 16,    │     16,384 │ average_pooling2… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_12[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_14[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        288 │ conv2d_17[0][0]   │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_18[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_12       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_14       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_17       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_18       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ mixed1              │ (None, 16, 16,    │          0 │ activation_12[0]… │
│ (Concatenate)       │ 288)              │            │ activation_14[0]… │
│                     │                   │            │ activation_17[0]… │
│                     │                   │            │ activation_18[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_22 (Conv2D)  │ (None, 16, 16,    │     18,432 │ mixed1[0][0]      │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_22[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_22       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_20 (Conv2D)  │ (None, 16, 16,    │     13,824 │ mixed1[0][0]      │
│                     │ 48)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_23 (Conv2D)  │ (None, 16, 16,    │     55,296 │ activation_22[0]… │
│                     │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        144 │ conv2d_20[0][0]   │
│ (BatchNormalizatio… │ 48)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        288 │ conv2d_23[0][0]   │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_20       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 48)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_23       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ average_pooling2d_2 │ (None, 16, 16,    │          0 │ mixed1[0][0]      │
│ (AveragePooling2D)  │ 288)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_19 (Conv2D)  │ (None, 16, 16,    │     18,432 │ mixed1[0][0]      │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_21 (Conv2D)  │ (None, 16, 16,    │     76,800 │ activation_20[0]… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_24 (Conv2D)  │ (None, 16, 16,    │     82,944 │ activation_23[0]… │
│                     │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_25 (Conv2D)  │ (None, 16, 16,    │     18,432 │ average_pooling2… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_19[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_21[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        288 │ conv2d_24[0][0]   │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_25[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_19       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_21       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_24       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_25       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ mixed2              │ (None, 16, 16,    │          0 │ activation_19[0]… │
│ (Concatenate)       │ 288)              │            │ activation_21[0]… │
│                     │                   │            │ activation_24[0]… │
│                     │                   │            │ activation_25[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_27 (Conv2D)  │ (None, 16, 16,    │     18,432 │ mixed2[0][0]      │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        192 │ conv2d_27[0][0]   │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_27       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_28 (Conv2D)  │ (None, 16, 16,    │     55,296 │ activation_27[0]… │
│                     │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 16, 16,    │        288 │ conv2d_28[0][0]   │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_28       │ (None, 16, 16,    │          0 │ batch_normalizat… │
│ (Activation)        │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_26 (Conv2D)  │ (None, 7, 7, 384) │    995,328 │ mixed2[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_29 (Conv2D)  │ (None, 7, 7, 96)  │     82,944 │ activation_28[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 384) │      1,152 │ conv2d_26[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 96)  │        288 │ conv2d_29[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_26       │ (None, 7, 7, 384) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_29       │ (None, 7, 7, 96)  │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ max_pooling2d_2     │ (None, 7, 7, 288) │          0 │ mixed2[0][0]      │
│ (MaxPooling2D)      │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ mixed3              │ (None, 7, 7, 768) │          0 │ activation_26[0]… │
│ (Concatenate)       │                   │            │ activation_29[0]… │
│                     │                   │            │ max_pooling2d_2[… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_34 (Conv2D)  │ (None, 7, 7, 128) │     98,304 │ mixed3[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 128) │        384 │ conv2d_34[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_34       │ (None, 7, 7, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_35 (Conv2D)  │ (None, 7, 7, 128) │    114,688 │ activation_34[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 128) │        384 │ conv2d_35[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_35       │ (None, 7, 7, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_31 (Conv2D)  │ (None, 7, 7, 128) │     98,304 │ mixed3[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_36 (Conv2D)  │ (None, 7, 7, 128) │    114,688 │ activation_35[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 128) │        384 │ conv2d_31[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 128) │        384 │ conv2d_36[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_31       │ (None, 7, 7, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_36       │ (None, 7, 7, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_32 (Conv2D)  │ (None, 7, 7, 128) │    114,688 │ activation_31[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_37 (Conv2D)  │ (None, 7, 7, 128) │    114,688 │ activation_36[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 128) │        384 │ conv2d_32[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 128) │        384 │ conv2d_37[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_32       │ (None, 7, 7, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_37       │ (None, 7, 7, 128) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ average_pooling2d_3 │ (None, 7, 7, 768) │          0 │ mixed3[0][0]      │
│ (AveragePooling2D)  │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_30 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ mixed3[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_33 (Conv2D)  │ (None, 7, 7, 192) │    172,032 │ activation_32[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_38 (Conv2D)  │ (None, 7, 7, 192) │    172,032 │ activation_37[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_39 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ average_pooling2… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_30[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_33[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_38[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_39[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_30       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_33       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_38       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_39       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ mixed4              │ (None, 7, 7, 768) │          0 │ activation_30[0]… │
│ (Concatenate)       │                   │            │ activation_33[0]… │
│                     │                   │            │ activation_38[0]… │
│                     │                   │            │ activation_39[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_44 (Conv2D)  │ (None, 7, 7, 160) │    122,880 │ mixed4[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_44[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_44       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_45 (Conv2D)  │ (None, 7, 7, 160) │    179,200 │ activation_44[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_45[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_45       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_41 (Conv2D)  │ (None, 7, 7, 160) │    122,880 │ mixed4[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_46 (Conv2D)  │ (None, 7, 7, 160) │    179,200 │ activation_45[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_41[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_46[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_41       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_46       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_42 (Conv2D)  │ (None, 7, 7, 160) │    179,200 │ activation_41[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_47 (Conv2D)  │ (None, 7, 7, 160) │    179,200 │ activation_46[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_42[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_47[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_42       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_47       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ average_pooling2d_4 │ (None, 7, 7, 768) │          0 │ mixed4[0][0]      │
│ (AveragePooling2D)  │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_40 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ mixed4[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_43 (Conv2D)  │ (None, 7, 7, 192) │    215,040 │ activation_42[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_48 (Conv2D)  │ (None, 7, 7, 192) │    215,040 │ activation_47[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_49 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ average_pooling2… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_40[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_43[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_48[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_49[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_40       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_43       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_48       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_49       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ mixed5              │ (None, 7, 7, 768) │          0 │ activation_40[0]… │
│ (Concatenate)       │                   │            │ activation_43[0]… │
│                     │                   │            │ activation_48[0]… │
│                     │                   │            │ activation_49[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_54 (Conv2D)  │ (None, 7, 7, 160) │    122,880 │ mixed5[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_54[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_54       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_55 (Conv2D)  │ (None, 7, 7, 160) │    179,200 │ activation_54[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_55[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_55       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_51 (Conv2D)  │ (None, 7, 7, 160) │    122,880 │ mixed5[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_56 (Conv2D)  │ (None, 7, 7, 160) │    179,200 │ activation_55[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_51[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_56[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_51       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_56       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_52 (Conv2D)  │ (None, 7, 7, 160) │    179,200 │ activation_51[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_57 (Conv2D)  │ (None, 7, 7, 160) │    179,200 │ activation_56[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_52[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 160) │        480 │ conv2d_57[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_52       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_57       │ (None, 7, 7, 160) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ average_pooling2d_5 │ (None, 7, 7, 768) │          0 │ mixed5[0][0]      │
│ (AveragePooling2D)  │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_50 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ mixed5[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_53 (Conv2D)  │ (None, 7, 7, 192) │    215,040 │ activation_52[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_58 (Conv2D)  │ (None, 7, 7, 192) │    215,040 │ activation_57[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_59 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ average_pooling2… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_50[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_53[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_58[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_59[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_50       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_53       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_58       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_59       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ mixed6              │ (None, 7, 7, 768) │          0 │ activation_50[0]… │
│ (Concatenate)       │                   │            │ activation_53[0]… │
│                     │                   │            │ activation_58[0]… │
│                     │                   │            │ activation_59[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_64 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ mixed6[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_64[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_64       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_65 (Conv2D)  │ (None, 7, 7, 192) │    258,048 │ activation_64[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_65[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_65       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_61 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ mixed6[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_66 (Conv2D)  │ (None, 7, 7, 192) │    258,048 │ activation_65[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_61[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_66[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_61       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_66       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_62 (Conv2D)  │ (None, 7, 7, 192) │    258,048 │ activation_61[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_67 (Conv2D)  │ (None, 7, 7, 192) │    258,048 │ activation_66[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_62[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_67[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_62       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_67       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ average_pooling2d_6 │ (None, 7, 7, 768) │          0 │ mixed6[0][0]      │
│ (AveragePooling2D)  │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_60 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ mixed6[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_63 (Conv2D)  │ (None, 7, 7, 192) │    258,048 │ activation_62[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_68 (Conv2D)  │ (None, 7, 7, 192) │    258,048 │ activation_67[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_69 (Conv2D)  │ (None, 7, 7, 192) │    147,456 │ average_pooling2… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_60[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_63[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_68[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 192) │        576 │ conv2d_69[0][0]   │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_60       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_63       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_68       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_69       │ (None, 7, 7, 192) │          0 │ batch_normalizat… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ mixed7              │ (None, 7, 7, 768) │          0 │ activation_60[0]… │
│ (Concatenate)       │                   │            │ activation_63[0]… │
│                     │                   │            │ activation_68[0]… │
│                     │                   │            │ activation_69[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ flatten (Flatten)   │ (None, 37632)     │          0 │ mixed7[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense (Dense)       │ (None, 1024)      │ 38,536,192 │ flatten[0][0]     │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_1 (Dense)     │ (None, 1)         │      1,025 │ dense[0][0]       │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 47,512,481 (181.25 MB)
 Trainable params: 38,537,217 (147.01 MB)
 Non-trainable params: 8,975,264 (34.24 MB)
In [33]:
callbacks = [model_checkpoint]
print(callbacks)
model_checkpoint.monitor, model_checkpoint.save_best_only, model_checkpoint.save_freq
[<keras.src.callbacks.model_checkpoint.ModelCheckpoint object at 0x7b4c546a8220>]
Out[33]:
('val_accuracy', True, 'epoch')

Compile model¶

In [34]:
model.compile(Adam(learning_rate=0.0001), loss=tf.losses.BinaryCrossentropy(), metrics=['accuracy'])
In [35]:
print("Model Name:", model.name)
print("Loss Function:", model.loss)
print("Optimizer:", model.optimizer)
print("Input Shape:", model.input_shape)
print("Output Shape:", model.output_shape)
Model Name: Chest-XRay-Pneumonia_iv3_model
Loss Function: <keras.src.losses.losses.BinaryCrossentropy object at 0x7b4cdb4af160>
Optimizer: <keras.src.optimizers.adam.Adam object at 0x7b4c5468f8b0>
Input Shape: (None, 150, 150, 3)
Output Shape: (None, 1)

Fit Model¶

In [36]:
%%time
epochs = 5    # 5 is enough
hist = model.fit(train, epochs=epochs, validation_data=val, callbacks=callbacks, verbose=1)
Epoch 1/5
65/65 ━━━━━━━━━━━━━━━━━━━━ 0s 1s/step - accuracy: 0.8385 - loss: 0.3633
Epoch 1: val_accuracy improved from -inf to 0.94676, saving model to /kaggle/working/models/Chest-XRay-Pneumonia_iv3_modelepoch_01 acc_0.9144 loss_0.2110 val_acc_0.9468 val_loss_0.1342.keras
65/65 ━━━━━━━━━━━━━━━━━━━━ 123s 2s/step - accuracy: 0.8397 - loss: 0.3610 - val_accuracy: 0.9468 - val_loss: 0.1342
Epoch 2/5
65/65 ━━━━━━━━━━━━━━━━━━━━ 0s 1s/step - accuracy: 0.9624 - loss: 0.1020
Epoch 2: val_accuracy improved from 0.94676 to 0.95718, saving model to /kaggle/working/models/Chest-XRay-Pneumonia_iv3_modelepoch_02 acc_0.9644 loss_0.0918 val_acc_0.9572 val_loss_0.1225.keras
65/65 ━━━━━━━━━━━━━━━━━━━━ 139s 2s/step - accuracy: 0.9624 - loss: 0.1018 - val_accuracy: 0.9572 - val_loss: 0.1225
Epoch 3/5
65/65 ━━━━━━━━━━━━━━━━━━━━ 0s 1s/step - accuracy: 0.9834 - loss: 0.0526
Epoch 3: val_accuracy improved from 0.95718 to 0.96065, saving model to /kaggle/working/models/Chest-XRay-Pneumonia_iv3_modelepoch_03 acc_0.9822 loss_0.0563 val_acc_0.9606 val_loss_0.1157.keras
65/65 ━━━━━━━━━━━━━━━━━━━━ 145s 2s/step - accuracy: 0.9834 - loss: 0.0527 - val_accuracy: 0.9606 - val_loss: 0.1157
Epoch 4/5
65/65 ━━━━━━━━━━━━━━━━━━━━ 0s 1s/step - accuracy: 0.9928 - loss: 0.0351
Epoch 4: val_accuracy did not improve from 0.96065
65/65 ━━━━━━━━━━━━━━━━━━━━ 137s 2s/step - accuracy: 0.9928 - loss: 0.0351 - val_accuracy: 0.9572 - val_loss: 0.1247
Epoch 5/5
65/65 ━━━━━━━━━━━━━━━━━━━━ 0s 1s/step - accuracy: 0.9948 - loss: 0.0208
Epoch 5: val_accuracy improved from 0.96065 to 0.96181, saving model to /kaggle/working/models/Chest-XRay-Pneumonia_iv3_modelepoch_05 acc_0.9947 loss_0.0244 val_acc_0.9618 val_loss_0.1078.keras
65/65 ━━━━━━━━━━━━━━━━━━━━ 144s 2s/step - accuracy: 0.9948 - loss: 0.0209 - val_accuracy: 0.9618 - val_loss: 0.1078
CPU times: user 29min 14s, sys: 4min 44s, total: 33min 58s
Wall time: 11min 57s
In [37]:
history = hist.history
hist_file = project_name + 'history.json'
hist_path = os.path.join(hist_dir, hist_file)
with open(hist_path, 'w') as f:
    json.dump(history, f)
    print('Training history saved to {}'.format(hist_path))
Training history saved to /kaggle/working/history/Chest-XRay-Pneumonia_history.json
In [38]:
# model_filenames = os.listdir(models_dir)
# def get_epoch(filename):
#     return int(filename.split(' ')[0][-2:])
# sorted_models = sorted(model_filenames, key=get_epoch)
# for model in sorted_models:
#     print(model,'\n')

for model in os.listdir(models_dir):
    print(model)
Chest-XRay-Pneumonia_iv3_modelepoch_03 acc_0.9822 loss_0.0563 val_acc_0.9606 val_loss_0.1157.keras
Chest-XRay-Pneumonia_iv3_modelepoch_05 acc_0.9947 loss_0.0244 val_acc_0.9618 val_loss_0.1078.keras
Chest-XRay-Pneumonia_iv3_modelepoch_01 acc_0.9144 loss_0.2110 val_acc_0.9468 val_loss_0.1342.keras
Chest-XRay-Pneumonia_iv3_modelepoch_02 acc_0.9644 loss_0.0918 val_acc_0.9572 val_loss_0.1225.keras

Plot accuracies and losses¶

In [39]:
title = project_name

def plot_losses(hist):
    fig = plt.figure()
    plt.plot(hist['loss'], color='teal', label='loss')
    plt.plot(hist['val_loss'], color='orange', label='val_loss')
    fig.suptitle(title+'Loss', fontsize=20)
    plt.legend(loc="upper right")
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.tight_layout()
    plt.savefig(figures_dir+'/' + title+'losses.png')
    plt.show()
    print('Saved losses to {}'.format(figures_dir+'/' + title+'losses.png'))
    
def plot_accuracies(hist):
    fig = plt.figure()
    plt.plot(hist['accuracy'], color='teal', label='accuracy')
    plt.plot(hist['val_accuracy'], color='orange', label='val_accuracy')
    fig.suptitle(title+'Accuracy', fontsize=20)
    plt.legend(loc="lower right")
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.tight_layout()
    plt.savefig(figures_dir+'/' + title+'accuracies.png')    
    plt.show()
    print('Saved accuracies to {}'.format(figures_dir+'/' + title+'accuracies.png'))   
In [40]:
plot_accuracies(history)
plot_losses(history)
No description has been provided for this image
Saved accuracies to /kaggle/working/figures/Chest-XRay-Pneumonia_accuracies.png
No description has been provided for this image
Saved losses to /kaggle/working/figures/Chest-XRay-Pneumonia_losses.png

Evaluate Model¶

In [41]:
# model_path = os.path.join(models_dir, sorted_models[9])
model_path = '/kaggle/working/models/Chest-XRay-Pneumonia_iv3_modelepoch_05 acc_0.9947 loss_0.0244 val_acc_0.9618 val_loss_0.1078.keras'

loaded_model = tf.keras.models.load_model(model_path)

print(loaded_model)
print(model_path)
print('Model Size: {:.2f} MB'.format(os.path.getsize(model_path) / (1024*1024)))
<Functional name=Chest-XRay-Pneumonia_iv3_model, built=True>
/kaggle/working/models/Chest-XRay-Pneumonia_iv3_modelepoch_05 acc_0.9947 loss_0.0244 val_acc_0.9618 val_loss_0.1078.keras
Model Size: 475.98 MB
In [42]:
pre = Precision()
re = Recall()
acc = BinaryAccuracy()

for batch in test.as_numpy_iterator(): 
    X, y = batch
    yhat = loaded_model.predict(X)
    pre.update_state(y, yhat)
    re.update_state(y, yhat)
    acc.update_state(y, yhat)
    
print('Precision : {}'.format(pre.result().numpy()))
print('Recall : {}'.format(re.result().numpy()))   
print('Accuracy : {}'.format(acc.result().numpy())) 
1/1 ━━━━━━━━━━━━━━━━━━━━ 3s 3s/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 692ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 656ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 658ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 708ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 1s 684ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 2s 2s/step
Precision : 0.9702970385551453
Recall : 0.9800000190734863
Accuracy : 0.9750000238418579

Make predictions¶

In [43]:
print(class_labels)
{'normal': 0, 'pneumonia': 1}
In [44]:
val_0_dir = test_dir_1
val_1_dir = test_dir_2

print(val_0_dir,'\n')
print(val_1_dir)
/kaggle/working/test/normal 

/kaggle/working/test/pneumonia
In [45]:
file_paths_val_0 = [os.path.join(val_0_dir, filename) for filename in os.listdir(val_0_dir)]
file_paths_val_1 = [os.path.join(val_1_dir, filename) for filename in os.listdir(val_1_dir)]

class_0_test = random.choice(file_paths_val_0)
class_1_test = random.choice(file_paths_val_1)

# Get the class label from the file path
class_label_0 = class_0_test.split('/')[-2]
class_label_1 = class_1_test.split('/')[-2]

# Get the class label value (0 or 1) from the class_labels dictionary
class_value_0 = class_labels[class_label_0]
class_value_1 = class_labels[class_label_1]

print(class_0_test)
print(class_1_test)
/kaggle/working/test/normal/NORMAL2-IM-0424-0001.jpeg
/kaggle/working/test/pneumonia/person94_bacteria_457.jpeg

Class 0¶

In [46]:
img = cv2.imread(class_0_test)
plt.imshow(img)
plt.title(f'Class Label: {class_value_0} ({class_label_0})', y=1.1)
plt.show()
No description has been provided for this image
In [47]:
resize = tf.image.resize(img, (input_shape[0], input_shape[1]))
plt.title(f'Class Label: {class_value_0} ({class_label_0})',y=1.1)
plt.imshow(resize.numpy().astype(int))
plt.show()
No description has been provided for this image
In [48]:
prediction = loaded_model.predict(np.expand_dims(resize/255, 0))
predicted_class = np.round(prediction).astype(int)
print(f"Predicted class is {predicted_class} {prediction}")
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 76ms/step
Predicted class is [[0]] [[0.00116001]]

Class 1¶

In [49]:
img = cv2.imread(class_1_test)
plt.imshow(img)
plt.title(f'Class Label: {class_value_1} ({class_label_1})',y=1.1)
plt.show()
No description has been provided for this image
In [50]:
resize = tf.image.resize(img, (input_shape[0], input_shape[1]))
plt.imshow(resize.numpy().astype(int))
plt.title(f'Class Label: {class_value_1} ({class_label_1})', y=1.1)
plt.show()
No description has been provided for this image
In [51]:
prediction = loaded_model.predict(np.expand_dims(resize/255, 0))
predicted_class = np.round(prediction).astype(int)
print(f"Predicted class is {predicted_class} {prediction}")
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 87ms/step
Predicted class is [[1]] [[0.9999954]]

Batch Predictions and Evaluate using metrices¶

In [52]:
def process_and_predictions(folder,images, to_predict):
    predictions = []
    correct = []
    wrong = []
    for image in images:
        img = cv2.imread(os.path.join(folder, image))
        resize = tf.image.resize(img, (input_shape[0], input_shape[1]))
        prediction = loaded_model.predict(np.expand_dims(resize / 255, 0))
        predicted_class = np.round(prediction).astype(int)
        predictions.append(predicted_class)
        if predicted_class == to_predict:
            correct.append(os.path.join(folder, image))
        else:
            wrong.append(os.path.join(folder, image))
    return predictions,correct, wrong
In [53]:
%%capture %%time
predictions_0, correct_0, wrong_0 = process_and_predictions(val_0_dir,os.listdir(val_0_dir), 0)
In [54]:
%%capture %%time
predictions_1, correct_1, wrong_1 = process_and_predictions(val_1_dir,os.listdir(val_1_dir), 1)
In [55]:
print(len(predictions_0), type(predictions_0))
print(len(predictions_1), type(predictions_1))
100 <class 'list'>
100 <class 'list'>
In [56]:
print(class_labels)
{'normal': 0, 'pneumonia': 1}
In [57]:
no_of_correct_0 = len(correct_0)
no_of_correct_1 = len(correct_1)

no_of_wrong_0 = len(wrong_0)
no_of_wrong_1 = len(wrong_1)

total_0 = no_of_correct_0 + no_of_wrong_0
total_1 = no_of_correct_1 + no_of_wrong_1

percent_of_correct_0 = (no_of_correct_0 / total_0)*100
percent_of_correct_1 = (no_of_correct_1 / total_1)*100


print('Predictions for class_0 {}'.format(next(key for key, val in class_labels.items() if val == 0)))
print('Number of correct predictions : {} out of {}'.format(no_of_correct_0, total_0))
print('Number of wrong predictions : {}'.format(no_of_wrong_0, total_0))
print('Percentage of correct predictions : {}\n'.format(percent_of_correct_0))

print('Predictions for class_1 {}'.format(next(key for key, val in class_labels.items() if val == 1)))
print('Number of correct predictions : {} out of {}'.format(no_of_correct_1, total_1))
print('Number of wrong predictions : {}'.format(no_of_wrong_1, total_1))
print('Percentage of correct predictions : {}\n'.format(percent_of_correct_1))
Predictions for class_0 normal
Number of correct predictions : 97 out of 100
Number of wrong predictions : 3
Percentage of correct predictions : 97.0

Predictions for class_1 pneumonia
Number of correct predictions : 98 out of 100
Number of wrong predictions : 2
Percentage of correct predictions : 98.0

In [58]:
y_pred = predictions_0 + predictions_1
y_pred_flat = [int(prediction.flatten()[0]) for prediction in y_pred]
y_true = [0] * len(predictions_0) + [1] * len(predictions_1)

report = classification_report(y_true, y_pred_flat)

print(report)
              precision    recall  f1-score   support

           0       0.98      0.97      0.97       100
           1       0.97      0.98      0.98       100

    accuracy                           0.97       200
   macro avg       0.98      0.97      0.97       200
weighted avg       0.98      0.97      0.97       200

In [59]:
# Compute confusion matrix
conf_matrix = confusion_matrix(y_true, y_pred_flat)

# Plot confusion matrix as heatmap
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', 
            xticklabels=['Predicted 0', 'Predicted 1'], 
            yticklabels=['Actual 0', 'Actual 1'])
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title(project_name+'Confusion Matrix')
plt.savefig(os.path.join(figures_dir,project_name+'Confusion Matrix.png'))
print('Image saved to {}'.format(os.path.join(figures_dir,project_name+'Confusion Matrix.png')))
plt.show()
Image saved to /kaggle/working/figures/Chest-XRay-Pneumonia_Confusion Matrix.png
No description has been provided for this image

Plot wrong predictions¶

Actual-0, Predicted-1¶

In [60]:
grid_plot(wrong_0[:24])
No description has been provided for this image

Actual-1, Predicted-0¶

In [61]:
grid_plot(wrong_1[:24])
No description has been provided for this image

Transfer Learning¶

Zip¶

In [ ]:
# shutil.rmtree(project_name)
In [62]:
os.makedirs(project_name, exist_ok=True)
In [63]:
for folder in [models_dir, hist_dir, figures_dir]:
    files = get_file_paths(folder)
    project_files = [item for item in files if project_name in item]
    destination_folder = os.path.join(os.getcwd(), project_name,os.path.basename(folder))
    os.makedirs(destination_folder, exist_ok=True)
    [shutil.move(file_path, destination_folder) for file_path in project_files]
print('Files moved')
Files moved
In [66]:
for root_dir, dirs, files in os.walk(project_name):
    print(root_dir)
    print(files)
    print()
Chest-XRay-Pneumonia_
[]

Chest-XRay-Pneumonia_/figures
['Chest-XRay-Pneumonia_ Distribution of Images.png', 'Chest-XRay-Pneumonia_losses.png', 'Chest-XRay-Pneumonia_Confusion Matrix.png', 'Chest-XRay-Pneumonia_accuracies.png']

Chest-XRay-Pneumonia_/history
['Chest-XRay-Pneumonia_history.json']

Chest-XRay-Pneumonia_/models
['Chest-XRay-Pneumonia_iv3_modelepoch_05 acc_0.9947 loss_0.0244 val_acc_0.9618 val_loss_0.1078.keras']

In [65]:
# to_move = ['Chest-XRay-Pneumonia_iv3_modelepoch_03 acc_0.9822 loss_0.0563 val_acc_0.9606 val_loss_0.1157.keras', 'Chest-XRay-Pneumonia_iv3_modelepoch_01 acc_0.9144 loss_0.2110 val_acc_0.9468 val_loss_0.1342.keras', 'Chest-XRay-Pneumonia_iv3_modelepoch_02 acc_0.9644 loss_0.0918 val_acc_0.9572 val_loss_0.1225.keras']

# for file in to_move:
#     file_path = os.path.join(project_name+'/models', file)
#     shutil.move(file_path, models_dir)
In [68]:
size = get_directory_size(project_name)
convert_bytes(size)
Out[68]:
'476.10 MB'
In [69]:
def create_zip():
    zip_path = os.path.join(zipfiles_dir,project_name)
    shutil.make_archive(zip_path, 'zip', project_name)
    print(os.listdir(zipfiles_dir))
    print(os.path.getsize(zip_path+'.zip')/(1024*1024) , ' MB')
In [70]:
create_zip()
['Chest-XRay-Pneumonia_.zip']
371.2098693847656  MB